package com.zero.clinic.shiro;

import com.zero.clinic.pojo.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyFormAuthenticationFilter extends FormAuthenticationFilter {

    //处理logout之后重新认证的页面乱跳问题
    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
        //清理掉乱跳的资源
        WebUtils.getAndClearSavedRequest(request);
        return super.onLoginSuccess(token, subject, request, response);
    }

    //认证前的验证码比对
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        // 1.将request和response对象转成Http类型的
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        // 2.从session中获取到系统自动生成的验证码信息，从req对象中获取到用户输入的验证码信息
        String code_in_session = (String) req.getSession().getAttribute("CODE_IN_SESSION");
        String inputVerifyCode = req.getParameter("inputVerifyCode");
        System.out.println(inputVerifyCode);
        // 3.比对code_in_session和inputVerifyCode，并返回数据至前端
        if (StringUtils.isNotBlank(code_in_session) && StringUtils.isNotBlank(inputVerifyCode)){
            if (!code_in_session.equalsIgnoreCase(inputVerifyCode)){  //如果输入的验证码不匹配
                req.setAttribute("errMsg", "验证码输入错误");
                req.getRequestDispatcher("/login.jsp").forward(req, resp);
                return false;
            }
        } else{
            if ("".equals(inputVerifyCode)){  //如果输入的验证码为空
                req.setAttribute("errMsg", "验证码不能为空");
                req.getRequestDispatcher("/login.jsp").forward(req, resp);
                return false;
            }
        }
        // 4.验证码匹配成功，直接调用父类方法，继续运行父类代码
        return super.onAccessDenied(request, response);
    }

    //获取浏览器中保存在本地的cookie登录信息
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        //1.从请求中获取Shiro主体对象
        Subject subject = getSubject(request, response);
        //2.从subject对象中获取Shiro框架中的session对象
        Session session = subject.getSession();
        //3.当subject没有被认证，且主体已经设置了“记住我”时
        if (!subject.isAuthenticated() && subject.isRemembered()){
            //4.从“记住我”的主体中获取主体身份，然后将主体身份共享到session对象中去
            session.setAttribute("USER_IN_SESSION",(User)subject.getPrincipal());
        }
        // 5.返回“主体是否认证通过” || “主体是否设置了记住我”; 其实就是返回true
        return subject.isAuthenticated() || subject.isRemembered();
    }
}
